import * as mars3d from "mars3d"
import { toRaw } from 'vue';
const Cesium = mars3d.Cesium

export const useTilesetLayer = (_mapInstance) => {
  let mapInstance: any = null
  let tiles3dLayer: any = null

  const initTilesetLayer = () => {
    mapInstance = toRaw(_mapInstance.value);

    tiles3dLayer = new mars3d.layer.TilesetLayer({
      name: "上海市区",
      flyTo: true,
      // 西渡视角
      center: { lat: 30.98081, lng: 121.424883, alt: 1282.9, heading: 357.9, pitch: -49 },
      // 整个上海市建模 todo
      url: "http://localhost/mars3d-data/3dtiles/sh/tileset.json",
      maximumScreenSpaceError: 4, // 增加误差容忍度，减少加载的模型细节
      maxMemory: 512, // 限制内存使用（MB）
      cullWithChildrenBounds: true, // 启用子节点包围盒剔除
      preloadWhenHidden: false, // 不可见时不预加载
      preferLeaves: true, // 优先加载叶子节点
      dynamicScreenSpaceError: true, // 启用动态屏幕空间误差
      dynamicScreenSpaceErrorDensity: 0.00278, // 动态屏幕空间误差密度
      dynamicScreenSpaceErrorFactor: 4.0, // 动态屏幕空间误差因子
      dynamicScreenSpaceErrorHeightFalloff: 0.25, // 动态屏幕空间误差高度衰减
      style: {
        color: {
          conditions: [
            ["${height} >= 300", "rgba(45, 0, 75, 0.5)"],
            ["${height} >= 200", "rgb(102, 71, 151)"],
            ["${height} >= 100", "rgb(170, 162, 204)"],
            ["${height} >= 50", "rgb(224, 226, 238)"],
            ["${height} >= 30", "rgb(252, 230, 200)"],
            ["${height} >= 20", "rgb(248, 176, 87)"],
            ["${height} >= 10", "rgb(198, 106, 11)"],
            ["true", "rgb(127, 59, 8)"]
          ]
        }
      },
      highlight: { type: "click", color: "#FFFF00" },
      popup: [
        { field: "objectid", name: "编号" },
        { field: "name", name: "名称" },
        { field: "height", name: "楼高", unit: "米" }
      ]
    })

    mapInstance.addLayer(tiles3dLayer)

    setStyle1()
  }

  function setStyle1() {
    // 天地图电子底图
    // mapInstance.basemap = 4

    tiles3dLayer.customShader = undefined
    // tiles3dLayer.marsJzwStyle = true // 打开建筑物特效（内置Shader代码）
    tiles3dLayer.marsJzwStyle = {
      baseHeight: 0.0, // 物体的基础高度，需要修改成一个合适的建筑基础高度
      heightRange: 66.0, // 高亮的范围  (baseHeight ~ baseHeight + heightRange)
      glowRange: 60.0, // 光环的移动范围
    }
  }

  function setStyle2() {
    tiles3dLayer.marsJzwStyle = false
    tiles3dLayer.customShader = new Cesium.CustomShader({
      lightingModel: Cesium.LightingModel.UNLIT,
      fragmentShaderText: `
      void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
      {
        vec4 position = czm_inverseModelView * vec4(fsInput.attributes.positionEC,1); // 位置

        // 注意shader中写浮点数是，一定要带小数点，否则会报错，比如0需要写成0.0，1要写成1.0
        float _baseHeight = 0.0; // 物体的基础高度，需要修改成一个合适的建筑基础高度
        float _heightRange = 80.0; // 高亮的范围(_baseHeight ~ _baseHeight + _heightRange)
        float _glowRange = 400.0; // 光环的移动范围(高度)

        // 建筑基础色
        float mars_height = position.z - _baseHeight;
        float mars_a11 = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
        float mars_a12 = mars_height / _heightRange + sin(mars_a11) * 0.1;

        material.diffuse = vec3(1.0, 1.0, 1.0); // 颜色
        material.diffuse *= vec3(mars_a12);// 渐变

        // 动态光环
        float time = fract(czm_frameNumber / 360.0);
        time = abs(time - 0.5) * 2.0;
        float mars_h = clamp(mars_height / _glowRange, 0.0, 1.0);
        float mars_diff = step(0.005, abs(mars_h - time));
        material.diffuse += material.diffuse * (1.0 - mars_diff);
      } `
    })
  }

  // customShader参数方式 夜景贴图
  function setStyle3() {
    // 设置黑色底图
    mapInstance.basemap = 18

    tiles3dLayer.marsJzwStyle = false
    tiles3dLayer.customShader = new Cesium.CustomShader({
      lightingModel: Cesium.LightingModel.UNLIT,
      varyings: {
        v_mars3d_normalMC: Cesium.VaryingType.VEC3
      },
      uniforms: {
        u_mars3d_texture: {
          value: new Cesium.TextureUniform({
            url: "https://data.mars3d.cn/img/textures/buildings.png"
          }),
          type: Cesium.UniformType.SAMPLER_2D
        }
      },
      vertexShaderText: /* glsl */ `
    void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput){
        v_mars3d_normalMC = vsInput.attributes.normalMC;
      }`,
      fragmentShaderText: /* glsl 如果贴图方向不对，用下面这个 */ `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      vec3 positionMC = fsInput.attributes.positionMC;
      if (dot(vec3(0.0, 0.0, 1.0), v_mars3d_normalMC) > 0.95) {
        //处理楼顶:统一处理成深色。
        material.diffuse = vec3(0.079, 0.107, 0.111);
      } else {
        //处理四个侧面: 贴一样的图
        float mars3d_width = 100.0;
        float mars3d_height = 100.0;
        float mars3d_textureX = 0.0;
        float mars3d_dotXAxis = dot(vec3(0.0, 1.0, 0.0), v_mars3d_normalMC);
        if (mars3d_dotXAxis > 0.52 || mars3d_dotXAxis < -0.52) {
          mars3d_textureX = mod(positionMC.x, mars3d_width) / mars3d_width;
        } else {
          mars3d_textureX = mod(positionMC.y, mars3d_width) / mars3d_width; //positionMC.z
        }
        float mars3d_textureY = mod(positionMC.z, mars3d_height) / mars3d_height; //positionMC.y
        material.diffuse = texture(u_mars3d_texture, vec2(mars3d_textureX, mars3d_textureY)).rgb;
      }
    }`
    })
  }

  const removeLayer = () => {
    if (tiles3dLayer) {
      mapInstance.basemap = 2021 // 切换到默认影像底图
      mapInstance.removeLayer(tiles3dLayer, true)
      tiles3dLayer = null
    }
  }

  return {
    initTilesetLayer,
    removeLayer,
    setStyle1,
    setStyle2,
    setStyle3
  }
}